package io.renren.iots.socket.client;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.SocketChannel;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;

import io.renren.htby.utils.IOTPBeanType;
import io.renren.modules.iotp.entity.IOTPBean;
import io.renren.modules.iotp.entity.IOTPBody;
import io.renren.modules.iotp.utils.IotpBodyUtils;
import io.renren.modules.iotp.utils.Msg_rellect;
import io.renren.modules.iots.entity.IotsEquipmentInfoEntity;
import io.renren.modules.iots.entity.IotsVariableInfoEntity;

/**
 * @ClassName: SingleSocketClientThread
 * @Description: 单例模式SingleSocketClientThread类
 * @author 周西栋
 * @date 2018年5月8日
 *
 */
public class SingleSocketReadThread implements Runnable {

	private Integer reccount = 0;
	// 创建读取的缓冲区
	ByteBuffer buffer = ByteBuffer.allocate(8354);

	/**
	 * 日志
	 */
	private Logger logger = LoggerFactory.getLogger(getClass());

	/**
	 * TCP字节数组流切片拼接工具
	 */
	Msg_rellect mr = null;

	/**
	 * 协议转换工具
	 */
	IotpBodyUtils ibu = null;

	/************************************************
	 * 单例模式
	 ************************************************/

	/**
	 * 创建一个新的实例 SingleSocketClientThread.
	 */
	private SingleSocketReadThread() {
		new Thread(this).start();
	}

	/**
	 * 私有对象变量
	 */
	private static final SingleSocketReadThread single = new SingleSocketReadThread();

	/**
	 * @Title: getInstance @Description: 饿汉模式--单例（静态工厂方法） @param @return 参数 @return
	 *         SingleSocketClientThread 返回类型 @throws
	 */
	public static SingleSocketReadThread getInstance() {
		return single;
	}

	/************************************************
	 * 单例模式
	 ************************************************/

	@Override
	public void run() {
		logger.info("我启动了一个读信息的线程");
		// 轮询访问selector
		while (!SocketClientUtils.SOCKETBEAN_MAP.isEmpty()) {
			try {
				Thread.sleep(1);
			} catch (InterruptedException e1) {
				e1.printStackTrace();
			}
			for (SocketBean socketBean : SocketClientUtils.SOCKETBEAN_MAP.values()) {
				try {
					if (socketBean.getConnectstatus() == 3) {
						try {
							if (socketBean.getSocketChannel() != null) {
								readBuffer(socketBean);
							}
						} catch (CancelledKeyException e) {
							continue;
						}
					}
				} catch (IOException e) {
					e.printStackTrace();
					continue;
				}
			}
		}
	}

	/**
	 * @Title: readBuffer @Description: 从缓冲区中读取数据 @param @param
	 *         socketBean @param @throws IOException 参数 @return void 返回类型 @throws
	 */
	public void readBuffer(SocketBean socketBean) throws IOException {
		SocketChannel channel = socketBean.getSocketChannel();
		if (!channel.isConnected()) {
			logger.info("客户端【 " + channel.getRemoteAddress() + " 】是不是处于连接状态： " + channel.isConnected());
			return;
		}
		try {
			reccount = channel.read(buffer);
		} catch (IOException e) {
			reccount = -1;
			logger.info("************* ************* ************* 我出错了 ************* ************* *************");
		}
		if (reccount == -1) {
			logger.info("断开..." + channel.socket().getRemoteSocketAddress());
			String address = channel.socket().getRemoteSocketAddress().toString().split("/")[1];
			logger.info("address:" + address);
			SocketClientUtils.SOCKETBEAN_MAP.get(address).setConnectstatus(4);
		} else if (reccount > 0) {
			buffer.flip();
			// 协议转换工具
			this.ibu = SocketClientUtils.CHANNEL_IOTPBODYUTILS_MAP.get(socketBean);
			byte[] data = this.ibu.getNewByteArray(buffer.array(), 0, reccount);
			// 信息拼接工具
			this.mr = SocketClientUtils.RELLECTMESSAGE.get(socketBean);
			List<byte[]> rellect_list = this.mr.rellect(data);
			if (rellect_list != null) {
				for (byte[] byte_array : rellect_list) {
					IOTPBean iotp = this.ibu.toIotpBean(byte_array);
					business(iotp);
				}
			}
			buffer.clear();
		}
	}

	/**
	 * 处理业务
	 * 
	 * @author lfy.xys
	 * @date 2018年6月28日
	 *
	 * @param iotp
	 */
	void business(IOTPBean iotp) {
		// 类型
		Integer type = iotp.getType();

		IOTPBeanType types = IOTPBeanType.getType(type);
		logger.info("枚举类型：" + types.getValue());
		
		switch (types) {
		case ReSyncEqmAndVarInfo:
			//22 获取 同步的 所有 设备和变量
			IOTPBody body = iotp.getBody();
			List<String> bodyList = body.getBodyList();
			
			//1、 这里可以得到 数据 的ip， a、将 eqm表 此ip的 所有 设备 设置  删除状态 为是    b、将 var表 此ip的 所有 变量 设置  删除状态 为是
			
			//2、 遍历 设备
			for (String string : bodyList) {
				IotsEquipmentInfoEntity eqmEntity = JSONObject.parseObject(string, IotsEquipmentInfoEntity.class);
				logger.info("eqmEntity:" + eqmEntity.getId() + ", " + eqmEntity.getPid());
				
				List<IotsVariableInfoEntity> varEntitys = eqmEntity.getList();
				//3、 遍历 变量。a 、新变量，插入 并 设置删除状态 为否， b、 旧变量 则修改，并 设置删除状态 为否。 c、 以前有的，现在没有的，依旧 删除状态 为是
				for (IotsVariableInfoEntity varEntity : varEntitys) {
					logger.info("varEntity:" + varEntity.getId() + ", " + varEntity.getPid());
				}
			}
			
			break;
		case ReIotsConfig:
			// 16 发送配置的回执消息
			
			break;
		default:
			break;
		}

	}

}